from flask import g, current_app
from flask_restful import Resource, inputs
from flask_restful.inputs import positive
from flask_restful.reqparse import RequestParser

from cache.article import ArticleInfoCache
from rpc.constants import USER_RECOMMENDS_COUNT
from utils.parser import channel_id
from utils.logging import write_trace_log
from rpc import reco_pb2_grpc, reco_pb2


class ArticleResource(Resource):
    """
    文章
    """
    def get(self, article_id):
        """
        获取文章详情
        :param article_id: int 文章id
        """
        qs_parser = RequestParser()
        qs_parser.add_argument('Trace', type=inputs.regex(r'^.+$'), required=False, location='headers')
        args = qs_parser.parse_args()

        # 从缓存层中查询文章数据
        article_cache = ArticleInfoCache(article_id)
        if article_cache.exists():
            article_dict = article_cache.get()

            # 向埋点日志中写入推荐系统需要的埋点信息
            if args.Trace:
                write_trace_log(args.Trace)

            # TODO 从缓存层中查询 文章内容/关注/评论/点赞情况

            # TODO 通过RPC向推荐系统索取相关文章推荐

            # TODO 使用持久化工具类 写入阅读历史

            return article_dict

        else:
            return {'messsage': 'Invalid article'}, 400


class ArticleListResource(Resource):
    """
    获取推荐文章列表数据
    """
    def __get_article_recommmends(self, channel_id, timestamp, article_num):
        """获取推荐的文章"""
        # 创建解析助手
        stub = reco_pb2_grpc.RecoServiceStub(current_app.rpc_reco)
        # 包装请求数据
        request = reco_pb2.RecoRequest()
        request.user_id = str(g.user_id) if g.user_id else "anomy"
        request.channel_id = channel_id
        request.time_stamp = timestamp
        request.article_num = article_num
        # 调用远程的函数
        return stub.article_recommend(request)


    def get(self):
        """获取首页推荐的文章"""
        # 解析参数
        parser = RequestParser()
        parser.add_argument('channel_id', location='args', type=channel_id, required=True)
        parser.add_argument('timestamp', location='args', type=positive, required=True)
        args = parser.parse_args()

        # 远程调用推荐系统的函数
        resp = self.__get_article_recommmends(args.channel_id, args.timestamp, USER_RECOMMENDS_COUNT)
        articles = []
        for article in resp.articles:
            article_dict = dict()
            article_id = article.article_id
            article_dict['article_id'] = article_id
            # 从缓存层中读取数据
            article_basic_dict = ArticleInfoCache(article_id).get()
            article_dict.update(article_basic_dict)
            article_dict['track'] = dict()
            article_dict['track']['click'] = article.track.click
            article_dict['track']['read'] = article.track.read
            article_dict['track']['collect'] = article.track.collect
            articles.append(article_dict)

        ret = {'articles': articles, "pre_time_stamp": resp.pre_time_stamp}
        return ret